package ru.JDiskCatalog.ui;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

import javax.swing.*;
import javax.swing.plaf.IconUIResource;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

import ru.JDiskCatalog.entities.FileInfo;
import ru.JDiskCatalog.util.NodeIcon;
import ru.JDiskCatalog.util.SqlUtil;

/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class MainWindow extends javax.swing.JFrame {
	private JToolBar ctlToolBar;		
	private JButton ctlExit;
	private JButton ctlCreateCatalog;
	private JButton ctlOpenCatalog;
	private JButton ctlAddMedia;	
	private JButton ctlSearchButton;
	private JTabbedPane ctlTabPane;
    private static String driver = "org.apache.derby.jdbc.EmbeddedDriver"; 
    
	/**
	* Auto-generated main method to display this JFrame
	*/
	public static void main(final String[] args) {		
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				MainWindow inst = new MainWindow(args);
				inst.setLocationRelativeTo(null);
				inst.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);							
				inst.setVisible(true);
			}
		});
	}
	
	public MainWindow(String[] args) {
		super();
		loadDriver();
		UIManager.put("swing.boldMetal", Boolean.FALSE);
		initGUI();
		
		if(args.length>0)
		{
			OpenBrowserWindow(args[0]);
		}
		
		addWindowListener(new WindowAdapter() {
			@Override
		    public void windowClosing(WindowEvent evt) 
			{
				WindowClosing(evt); 
			}					
		});
	}
	
	private void WindowClosing(WindowEvent evt) 
	{		            
		Component[] arrComponents=ctlTabPane.getComponents();
		for(Component objComponent : arrComponents)
			if(objComponent instanceof CatalogBrowser)
			{
				CatalogBrowser objBrowser=(CatalogBrowser)objComponent;
				objBrowser.Cleanup();
			}
		
        try
        {
            // the shutdown=true attribute shuts down Derby
            DriverManager.getConnection("jdbc:derby:;shutdown=true");
        }
        catch (SQLException se)
        {
            if (( (se.getErrorCode() == 50000)
                    && ("XJ015".equals(se.getSQLState()) ))) {
                // we got the expected exception
                System.out.println("Derby shut down normally");
                // Note that for single database shutdown, the expected
                // SQL state is "08006", and the error code is 45000.
            } else {
                // if the error code or SQLState is different, we have
                // an unexpected exception (shutdown failed)
                System.err.println("Derby did not shut down normally");
            }
        }
	}	
	
	private void initGUI() {
		try {
			this.setExtendedState(Frame.MAXIMIZED_BOTH);
			setTitle("JDiskCatalog");
			ctlToolBar = new JToolBar();
			getContentPane().add(ctlToolBar, BorderLayout.NORTH);
			ctlToolBar.setFloatable(false);
			{
				ctlTabPane = new JTabbedPane();
				getContentPane().add(ctlTabPane, BorderLayout.CENTER);				
			}
			setSize(400, 300);
			{
				ctlCreateCatalog=new JButton();
				ctlToolBar.add(ctlCreateCatalog);
				ctlCreateCatalog.setText("Create catalog");
				ctlCreateCatalog.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent evt) {
						CreateCatalogActionPerformed(evt);
					}
				});		
				
				ctlOpenCatalog=new JButton();
				ctlToolBar.add(ctlOpenCatalog);
				ctlOpenCatalog.setText("Open catalog");
				ctlOpenCatalog.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent evt) {
						OpenCatalogActionPerformed(evt);
					}
				});		
				
				ctlAddMedia=new JButton();
				ctlToolBar.add(ctlAddMedia);
				ctlAddMedia.setText("Add media");
				ctlAddMedia.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent evt) {
						addMediaMenuItemActionPerformed(evt);
					}
				});
				
				ctlSearchButton=new JButton();
				ctlToolBar.add(ctlSearchButton);
				ctlSearchButton.setText("Search");
				ctlSearchButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent evt) {
						SearchActionPerformed(evt);
					}
				});				
				
				ctlExit = new JButton();
				ctlToolBar.add(ctlExit);
				ctlExit.setText("Exit");
				ctlExit.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent evt) {
						exitMenuItemActionPerformed(evt);
					}
				});		
				
				UIManager.put("Tree.collapsedIcon", new IconUIResource(new NodeIcon('+')));
				UIManager.put("Tree.expandedIcon",  new IconUIResource(new NodeIcon('-')));				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
   	
	
    /**
     * Loads the appropriate JDBC driver for this environment/framework. For
     * example, if we are in an embedded environment, we load Derby's
     * embedded Driver, <code>org.apache.derby.jdbc.EmbeddedDriver</code>.
     */
    private void loadDriver() {
        /*
         *  The JDBC driver is loaded by loading its class.
         *  If you are using JDBC 4.0 (Java SE 6) or newer, JDBC drivers may
         *  be automatically loaded, making this code optional.
         *
         *  In an embedded environment, this will also start up the Derby
         *  engine (though not any databases), since it is not already
         *  running. In a client environment, the Derby engine is being run
         *  by the network server framework.
         *
         *  In an embedded environment, any static Derby system properties
         *  must be set before loading the driver to take effect.
         */
        try {
            Class.forName(driver).newInstance();
            System.out.println("Loaded the appropriate driver");
        } catch (ClassNotFoundException cnfe) {
            System.err.println("\nUnable to load the JDBC driver " + driver);
            System.err.println("Please check your CLASSPATH.");
            cnfe.printStackTrace(System.err);
        } catch (InstantiationException ie) {
            System.err.println(
                        "\nUnable to instantiate the JDBC driver " + driver);
            ie.printStackTrace(System.err);
        } catch (IllegalAccessException iae) {
            System.err.println(
                        "\nNot allowed to access the JDBC driver " + driver);
            iae.printStackTrace(System.err);
        }
    }
     
    private void CreateCatalogActionPerformed(ActionEvent evt)
    {
		final JFileChooser fc = new JFileChooser();
		fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		int returnVal = fc.showOpenDialog(this);
		if(returnVal == JFileChooser.APPROVE_OPTION)
		{
			String connectionString="jdbc:derby:"+fc.getSelectedFile().getPath()+";create=true";						
			Statement s=null;
			
			try
			{
				File objBatch=new File("db_create.sql");
				if(objBatch.exists())
				{
					FileInputStream objStream=new FileInputStream(objBatch);
					String strFileContent=new java.util.Scanner(objStream,"UTF-8").useDelimiter("\\A").next();
					String[] arrCommands=strFileContent.split(";");

					s=DriverManager.getConnection(connectionString).createStatement();
					for(String strCommand : arrCommands)					
						s.addBatch(strCommand);
					
					s.executeBatch();					
					
					OpenBrowserWindow(fc.getSelectedFile().getPath());
				}
			}
			catch(SQLException sqle)
			{		
				SqlUtil.ReportSQLException(sqle);
			}
			catch(Exception ex)
			{
				ex.printStackTrace();
			}
			finally
			{
				SqlUtil.CloseStatement(s);
			}					
		}
    }
    
    private void OpenCatalogActionPerformed(ActionEvent evt)
    {
		final JFileChooser fc = new JFileChooser();
		fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		int returnVal = fc.showOpenDialog(this);
		if(returnVal == JFileChooser.APPROVE_OPTION)
		{					
			OpenBrowserWindow(fc.getSelectedFile().getPath());
		}
    }    
    
    private void OpenBrowserWindow(String strDBPath)
    {
		CatalogBrowser objBrowser=new CatalogBrowser(strDBPath);
		ctlTabPane.addTab("Catalog browser", objBrowser);
		ctlTabPane.setSelectedComponent(objBrowser);
		
		ButtonTabComponent objTabButton=new ButtonTabComponent(ctlTabPane);		
		ctlTabPane.setTabComponentAt(ctlTabPane.getSelectedIndex(),objTabButton);
    }
    
    
     private void addMediaMenuItemActionPerformed(ActionEvent evt) {
    	 if(ctlTabPane.getSelectedComponent() instanceof CatalogBrowser)
    	 {
     		CatalogBrowser objBrowser=(CatalogBrowser)ctlTabPane.getSelectedComponent();
	    	 MediaEditDlg objPC=new MediaEditDlg(this,objBrowser.getDBConnection());
	    	 objPC.setLocationRelativeTo(null);
	    	 objPC.setVisible(true);
	    	 
	    	 if(objPC.DialogSuccess)
	    		 objBrowser.ReloadTree();				
    	 }
     }
     
     private void SearchActionPerformed(ActionEvent evt)
     {
    	 if(ctlTabPane.getSelectedComponent() instanceof CatalogBrowser)
    	 {
    		CatalogBrowser objBrowser=(CatalogBrowser)ctlTabPane.getSelectedComponent();
			CatalogSearch objSearch=new CatalogSearch(objBrowser.getDBConnection());
			ctlTabPane.addTab("Search catalog", objSearch);
			ctlTabPane.setSelectedComponent(objSearch);
			
			ButtonTabComponent objTabButton=new ButtonTabComponent(ctlTabPane);		
			ctlTabPane.setTabComponentAt(ctlTabPane.getSelectedIndex(),objTabButton);
    	 }
     }
     
     private void exitMenuItemActionPerformed(ActionEvent evt) {
 		this.processWindowEvent(
	            new WindowEvent(
	                  this, WindowEvent.WINDOW_CLOSING));
     }
}
